package com.mall.b2c.service.impl;

import com.google.common.collect.Lists;
import com.mall.b2c.Setting;
import com.mall.b2c.bean.GoodsBean;
import com.mall.b2c.bean.GoodsSort;
import com.mall.b2c.domain.goods.BrandDomain;
import com.mall.b2c.domain.goods.GoodsCategoryDomain;
import com.mall.b2c.domain.goods.GoodsDomain;
import com.mall.b2c.domain.member.MemberDomain;
import com.mall.b2c.enums.PrescribeType;
import com.mall.b2c.lucene.GroupField;
import com.mall.b2c.lucene.SearchGroupData;
import com.mall.b2c.plugin.search.SearchSelector;
import com.mall.b2c.service.GoodsCategoryService;
import com.mall.b2c.service.LuceneService;
import com.mall.b2c.service.MemberService;
import com.mall.b2c.util.DictionaryUtils;
import com.mall.b2c.util.SettingUtils;
import com.mall.common.bean.Pager;
import com.mall.common.enums.MedicalInsuranceType;
import com.mall.common.hibernate.Finder;
import com.mall.common.util.AppContext;
import com.mall.common.util.DateUtils;
import com.mall.common.util.EntityManagerHelper;
import com.mall.common.util.UploadUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.*;
import org.apache.lucene.search.grouping.GroupDocs;
import org.apache.lucene.search.grouping.SearchGroup;
import org.apache.lucene.search.grouping.TermFirstPassGroupingCollector;
import org.apache.lucene.search.grouping.TermSecondPassGroupingCollector;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.jpa.Search;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.wltea.analyzer.lucene.IKAnalyzer;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Future;

/**
 *
 * @author wangzx
 *
 */
@Service
@Transactional
public class LuceneServiceImpl implements LuceneService{

    private Logger log = Logger.getLogger(this.getClass());
    private static final int BATCH_COMMIT_SIZE = 2000;
    @Resource private GoodsCategoryService goodsCategoryService;
    @Resource private MemberService memberService;

    /**
     * 手动建立商品索引
     * 采取异步方式实现
     */
    @Async
    public  Future<Integer> indexGoods(Date beginDate,Date endDate, Long goodsCategoryId) {
        EntityManager entityManager = EntityManagerHelper.getEntityManager();
        FullTextEntityManager fulltextentitymanager = Search.getFullTextEntityManager(entityManager);
        try {
            Finder finder = Finder.create("from GoodsDomain goods where goods.isMarketable = true");
            if(beginDate != null){
                finder.append(" and goods.modifyDate >= :beginDate");
                finder.setParam("beginDate", beginDate);
            }
            if(endDate != null){
                finder.append(" and goods.modifyDate < :endDate");
                finder.setParam("endDate", DateUtils.getDateNextDay(endDate, 1));
            }
            if(goodsCategoryId != null) {
                GoodsCategoryDomain goodsCategory = goodsCategoryService.find(goodsCategoryId);
                if(goodsCategory != null) {
                    finder.append(" and goods.goodsCategory.code like :goodsCategoryCode")
                            .setParam("goodsCategoryCode", goodsCategory.getCode()+"%");
                }

            }
            List<GoodsDomain> goodsList = finder.findHQLList();
            int index = 0;
            for (GoodsDomain goods : goodsList) {
                index++;
                fulltextentitymanager.index(goods);
                if(index % BATCH_COMMIT_SIZE == 0){
                    fulltextentitymanager.flushToIndexes();
                }
            }
            fulltextentitymanager.flushToIndexes();
            fulltextentitymanager.clear();
            return new AsyncResult<Integer>(goodsList.size());
        } catch (Exception e) {
            log.error("商品索引建立失败", e);
        }
        return new AsyncResult<Integer>(0);
    }

    /**
     * 手动更新商品索引
     * 采取异步方式实现
     */
    @Async
    @Override
    public void updateIndexGoods(Long[] ids) {
        try {
            EntityManager entityManager = EntityManagerHelper.getEntityManager();
            FullTextEntityManager fulltextentitymanager = Search.getFullTextEntityManager(entityManager);
            CriteriaBuilder cb = fulltextentitymanager.getCriteriaBuilder();
            CriteriaQuery<GoodsDomain> query = cb.createQuery(GoodsDomain.class);
            Root<GoodsDomain> root = query.from(GoodsDomain.class);
            List<GoodsDomain> goodsList =
                    entityManager.createQuery(query.where(root.get("id").in(Lists.newArrayList(ids)))).getResultList();
            int index = 0;
            for (GoodsDomain goods : goodsList) {
                index++;
                fulltextentitymanager.index(goods);
                if(index % BATCH_COMMIT_SIZE == 0) {
                    fulltextentitymanager.flushToIndexes();
                }
            }
            fulltextentitymanager.flushToIndexes();
            fulltextentitymanager.clear();
        }catch (Exception e){
            log.error("更新商品索引失败", e);
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<GoodsDomain> simpleSearch(String keyword, Integer count) {
        if(StringUtils.isNotBlank(keyword)) {
            keyword = keyword.trim().toUpperCase();
        }
        String escapedKeyword = QueryParser.escape(keyword);
        try {
            //组合内层的逻辑查询
            BooleanQuery innerBooleanQuery = assembleInnerQuery(escapedKeyword);
            //组合外部的逻辑查询
            BooleanQuery booleanQuery = new BooleanQuery();
            booleanQuery.add(innerBooleanQuery, Occur.MUST);
            TermQuery isMarketableTermQuery = new TermQuery(new Term("isMarketable", "true"));
            booleanQuery.add(isMarketableTermQuery, Occur.MUST);

            EntityManager entityManager = EntityManagerHelper.getEntityManager();
            FullTextEntityManager fulltextentitymanager = Search.getFullTextEntityManager(entityManager);
            FullTextQuery fulltextquery = fulltextentitymanager.createFullTextQuery(booleanQuery, GoodsDomain.class);
            fulltextquery.setFirstResult(0);
            fulltextquery.setMaxResults(count);
            return fulltextquery.getResultList();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public JSONArray searchTip(List<String> keywords, Integer count) {
        if(CollectionUtils.isEmpty(keywords)) {
            return null;
        }

        JSONArray arr = new JSONArray();
        IndexSearcher searcher = null;
        try {
            String indexPath = AppContext.getAppRealPath(SettingUtils.get().getLuceneGoodsIndexPath());
            IndexReader reader = IndexReader.open(FSDirectory.open(new File(indexPath)));
            searcher = new IndexSearcher(reader);
            Iterator<String> iterList = keywords.iterator();
            while(iterList.hasNext()){
                String escapedKeyword = QueryParser.escape(iterList.next());
                if(StringUtils.isBlank(escapedKeyword)){
                    continue;
                }else{
                    escapedKeyword = escapedKeyword.toUpperCase();
                }
                //组合内层的逻辑查询
                BooleanQuery innerBooleanQuery = assembleInnerQuery(escapedKeyword);
                //组合外部的逻辑查询
                BooleanQuery booleanQuery = new BooleanQuery();
                booleanQuery.add(innerBooleanQuery, Occur.MUST);
                TermQuery isMarketableTermQuery = new TermQuery(new Term("isMarketable", "true"));
                booleanQuery.add(isMarketableTermQuery, Occur.MUST);

                //拼音去重
                DuplicateFilter duplicateFilterGoodsName = new DuplicateFilter("goodsName");
                FilteredQuery filteredQuery  = new FilteredQuery(booleanQuery, duplicateFilterGoodsName);

                TopDocs tdocs = searcher.search(filteredQuery, count);
                ScoreDoc[] sdocs = tdocs.scoreDocs;
                for (ScoreDoc sdoc : sdocs) {
                    Document doc = searcher.doc(sdoc.doc);
                    JSONObject jo = new JSONObject();
                    String name = doc.get("goodsName");
                    String pyName = doc.get("pyName");
                    jo.put("name", name);
                    jo.put("pyName", StringUtils.isBlank(pyName) ? pyName : pyName.toUpperCase());
                    arr.add(jo);
                }
            }
            searcher.close();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return arr;
    }

    @SuppressWarnings("unchecked")
	@Override
    public Map<String, Object> searchIndex(Pager pager, String keywords, Map<String, String> filterMap, String orderby) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        List<SearchGroupData> selectList = Lists.newLinkedList();
        Integer totalCount = pager.getTotalCount();// 总数
        if (StringUtils.isNotEmpty(pager.getKeyword())) {
            keywords = pager.getKeyword();
        }
        // 查询关键字
        List<GoodsDomain> goods = null;
        IndexReader indexReader = null;
        //组合外部的逻辑查询
        BooleanQuery booleanQuery = new BooleanQuery();
        try {
            if (StringUtils.isNotBlank(keywords)) {
                keywords = keywords.trim().toUpperCase();
            }
            String escapedKeyword = QueryParser.escape(keywords);
            //组合内层的逻辑查询
            BooleanQuery innerBooleanQuery = assembleInnerQuery(escapedKeyword);
            booleanQuery.add(innerBooleanQuery, Occur.MUST);
            TermQuery isMarketableTermQuery = new TermQuery(new Term("isMarketable", "true"));
            booleanQuery.add(isMarketableTermQuery, Occur.MUST);
            /**
             * 商品分类,剂型,处方类型,医保类型筛选
             */
            if (StringUtils.isNotBlank(filterMap.get("categoryCode"))) {
                WildcardQuery categoryCodeWildcardQuery = new WildcardQuery(new Term("goodsCategory.code", filterMap.get("categoryCode") + "*"));
                booleanQuery.add(categoryCodeWildcardQuery, Occur.MUST);
            }

            String brandName = filterMap.get("brandName");
            if(StringUtils.isNotBlank(brandName)){
                TermQuery brandTermQuery = new TermQuery(new Term("brand.name", brandName));
                booleanQuery.add(brandTermQuery, Occur.MUST);
            }

            String keyword = filterMap.get("keyword");
            if(StringUtils.isNotBlank(keyword)){
                WildcardQuery keywordWildcardQuery = new WildcardQuery(new Term("keyword", "*"+keyword + "*"));
                booleanQuery.add(keywordWildcardQuery, Occur.MUST);
            }

            /**排序：
             * 1、默认的相关度排序
             * 	a 搜索时指定Field的boost属性，影响相关度排序，boost默认值为1.0f，旧得分*boost = 新得分
             * 	b 建立索引时指定Document的boost属性，影响相关度排序，boost默认值为1.0f, 旧得分*boost = 新得分
             * 2、指定的排序
             */
            SortField sortFields[] = null;
            //指定的排序的排序，默认的相关度排序不起作用
            if (StringUtils.isNotEmpty(orderby)) {
                if (orderby.equals(GoodsSort.SalesDesc.name())) {
                    sortFields = new SortField[]{new SortField("sales", SortField.INT, true)};
                } else if (orderby.equals(GoodsSort.CommentsDesc.name())) {
                    sortFields = new SortField[]{new SortField("cmts", SortField.INT, true)};
                } else if (orderby.equals(GoodsSort.PriceAsc.name())){
                    sortFields = new SortField[]{new SortField("price", SortField.DOUBLE, false)};
                } else if (orderby.equals(GoodsSort.PriceDesc.name())){
                    sortFields = new SortField[]{new SortField("price",SortField.DOUBLE, true)};
                }
            }
            EntityManager entityManager = EntityManagerHelper.getEntityManager();
            FullTextEntityManager fulltextentitymanager = Search.getFullTextEntityManager(entityManager);
            FullTextQuery fulltextquery = fulltextentitymanager.createFullTextQuery(booleanQuery, GoodsDomain.class);
            if (sortFields != null) {
                fulltextquery.setSort(new Sort(sortFields));
            }
            //分页
            totalCount = fulltextquery.getResultSize();
            fulltextquery.setFirstResult((pager.getPageNumber() - 1) * pager.getPageSize());
            fulltextquery.setMaxResults(pager.getPageSize());
            //获取数据
            goods = fulltextquery.getResultList();


            fulltextquery.getFacetManager();

            /**
             * 分组信息
             */
            String indexPath = AppContext.getAppRealPath(SettingUtils.get().getLuceneGoodsIndexPath());
            indexReader = IndexReader.open(FSDirectory.open(new File(indexPath)));

            /**1、品牌*/
            SearchGroupData brandData = getGroupCollector(indexReader, booleanQuery, "brand.name");
            brandData.setName("品牌");
            brandData.setMark("brand");
            selectList.add(brandData);


            /**2、三级分类*/
            SearchGroupData categoryData = getGroupCollector(indexReader, booleanQuery, "goodsCategory.code");
            categoryData.setName("分类");
            categoryData.setMark("categoryCode");
            selectList.add(categoryData);



            /**3、剂型*/
            /*SearchGroupData drugFormData = getGroupCollector(indexReader, booleanQuery, "drugForm");
            drugFormData.setName("剂型");
            drugFormData.setMark("drugForm");
            selectList.add(drugFormData);
*/
            /**4、处方类型*/
            /*SearchGroupData prescribeTypeData = getGroupCollector(indexReader, booleanQuery, "prescribeType");
            prescribeTypeData.setName("处方类型");
            prescribeTypeData.setMark("prescribeType");
            selectList.add(prescribeTypeData);*/


            /**5、医保类型*/
           /* SearchGroupData medicalInsuranceTypeData = getGroupCollector(indexReader, booleanQuery, "medicalInsuranceType");
            medicalInsuranceTypeData.setName("医保类型");
            medicalInsuranceTypeData.setMark("medicalInsuranceType");
            selectList.add(medicalInsuranceTypeData);*/

            /**6、生产厂家*/
           /* SearchGroupData manufacturerData = getGroupCollector(indexReader, booleanQuery, "manufacturer");
            manufacturerData.setMark("manufacturer");
            manufacturerData.setName("生产厂家");
            selectList.add(manufacturerData);*/
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("pager", pager);
            return resultMap;
        } finally {
            if (indexReader != null) {
                try {
                    indexReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        pager.setTotalCount(totalCount);

        if(!CollectionUtils.isEmpty(goods)){
            String memberId = filterMap.get("memberId");
            MemberDomain member = null;
            if(StringUtils.isNotBlank(memberId)){
               member = memberService.find(Long.valueOf(memberId));
            }
            List<GoodsBean> beans = Lists.newLinkedList();

            Setting setting = SettingUtils.get();
            SimpleHTMLFormatter formatter =
                    new SimpleHTMLFormatter("<b><font color=\""
                            +setting.getLuceneHighlighterColor()+"\">", "</font></b>");
            QueryScorer qs = new QueryScorer(booleanQuery);
            Highlighter highlighter = new Highlighter( formatter, qs);

            for(GoodsDomain g : goods){
                GoodsBean bean = new GoodsBean(g, member);
                //是否启用高亮显示，可配置
                if(setting.getLuceneEnableHighlighter() != null
                        && setting.getLuceneEnableHighlighter()){
                    try {
                        String highlighterResult =  highlighter.getBestFragment(
                                new IKAnalyzer(), keywords, bean.getName());
                        if(StringUtils.isBlank(highlighterResult)){
                            highlighterResult = bean.getName();
                        }
                        bean.setHighlighter(highlighterResult);
                    } catch (Exception e) {
                        bean.setHighlighter(bean.getName());
                    }
                }else{
                    bean.setHighlighter(bean.getName());
                }
                beans.add(bean);
            }
            pager.setList(beans);
        }

        pager.setKeyword(keywords);
        resultMap.put("pager", pager);
        resultMap.put("selectorList", selectList);
        List<SearchSelector> sortList = new ArrayList<SearchSelector>();
        for (GoodsSort sort : GoodsSort.values()) {
            if(GoodsSort.PriceAsc.name().equals(orderby) && sort.equals(GoodsSort.PriceAsc)) {
                continue;
            }

            if(!GoodsSort.PriceAsc.name().equals(orderby) && sort.equals(GoodsSort.PriceDesc)){
                continue;
            }

            SearchSelector selector = new SearchSelector();
            selector.setName(DictionaryUtils.getEnumName(sort));
            selector.setUrl(sort.name());
            if (StringUtils.isBlank(orderby)) {
                if(sort.equals(GoodsSort.TopDesc)){
                    selector.setSelected(Boolean.TRUE);
                }
            }else if(sort.equals(GoodsSort.PriceAsc) && orderby.equals(GoodsSort.PriceDesc.name())){
                selector.setSelected(Boolean.TRUE);
            }else if(sort.equals(GoodsSort.PriceDesc) && orderby.equals(GoodsSort.PriceAsc.name())){
                selector.setSelected(Boolean.TRUE);
            }else if(sort.name().equals(orderby)){
                selector.setSelected(Boolean.TRUE);
            }
            sortList.add(selector);
        }
        resultMap.put("sortList", sortList);
        return resultMap;
    }

    /**
     *获取分组信息
    */
    public SearchGroupData getGroupCollector(IndexReader indexReader, Query query, String field) throws IOException {
        try{
            TermFirstPassGroupingCollector fistCollector = new TermFirstPassGroupingCollector(field, Sort.INDEXORDER, 500);//限制输出分组结果数量500
            CachingCollector cachedCollector = CachingCollector.create(fistCollector, true, 16.0);
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
            indexSearcher.search(query, cachedCollector);
            Collection<SearchGroup<String>> topGroups = fistCollector.getTopGroups(0, true);
            if(CollectionUtils.isEmpty(topGroups)){
               return new SearchGroupData();
            }

            TermSecondPassGroupingCollector c2 =
                    new TermSecondPassGroupingCollector(
                            field, topGroups, Sort.INDEXORDER, Sort.RELEVANCE, 1, true, true, true);
            if (cachedCollector.isCached()) {
                // 被缓存的话，就用缓存
                cachedCollector.replay(c2);
            } else {
                // 超出缓存大小，重新执行一次查询
                indexSearcher.search(query, c2);
            }
           return processGroupCollector(c2, field);
        }catch (Exception e){
            return new SearchGroupData();
        }
    }

    public SearchGroupData processGroupCollector(TermSecondPassGroupingCollector secondCollector, String field) {
        SearchGroupData groupData= new SearchGroupData();
        if(StringUtils.isBlank(field)) {
            return groupData;
        }
        List<GroupField> result = Lists.newArrayList();
        GroupDocs<String>[] groupDocsArr = secondCollector.getTopGroups(0).groups;
        //排序
        Arrays.sort(groupDocsArr, new Comparator<GroupDocs>() {
            @Override
            public int compare(GroupDocs o1, GroupDocs o2) {
                return o2.totalHits - o1.totalHits;
            }
        });

        if(field.equals("goodsCategory.code") || field.equals("goodsCategory.parentCode")) {
            List<String> values = Lists.newArrayList();
            for (GroupDocs<String> groupDocs : groupDocsArr) {
                String value = groupDocs.groupValue;
                if(StringUtils.isNotBlank(value)) {
                    result.add(new GroupField(value, value, groupDocs.totalHits));
                    values.add(value);
                }
            }
            if(!CollectionUtils.isEmpty(result)){
                Finder finder = Finder.create("from GoodsCategoryDomain bean where bean.code in (:codes)");
                finder.setParamList("codes", values.toArray());
                List<GoodsCategoryDomain> cateList = finder.findHQLList();
                for(GoodsCategoryDomain cate : cateList){
                    for(GroupField groupField:result){
                        if(groupField.getValue().equals(cate.getCode())){
                            result.add(new GroupField(groupField.getValue(), cate.getName(), groupField.getCount()));
                        }
                    }
                }
            }
        } else if(field.equals("prescribeType")){
            for (GroupDocs<String> groupDocs : groupDocsArr) {
                String value = groupDocs.groupValue;
                if(StringUtils.isNotBlank(value)) {
                    result.add(new GroupField(value,
                            DictionaryUtils.getEnumName(PrescribeType.valueOf(value)), groupDocs.totalHits));
                }
            }
        } else if(field.equals("medicalInsuranceType")) {
            for (GroupDocs<String> groupDocs : groupDocsArr) {
                String value = groupDocs.groupValue;
                if(StringUtils.isNotBlank(value)) {
                    result.add(new GroupField(value,
                            DictionaryUtils.getEnumName(MedicalInsuranceType.valueOf(value)), groupDocs.totalHits));
                }
            }
        } else if(field.equals("brand.name")){
            List<String> values = Lists.newArrayList();
            for (GroupDocs<String> groupDocs : groupDocsArr) {
                String value = groupDocs.groupValue;
                if(StringUtils.isNotBlank(value)){
                    values.add(value);
                }
            }
            if(!CollectionUtils.isEmpty(values)){
                Finder finder = Finder.create("from BrandDomain bean where bean.name in (:values)");
                finder.setParamList("values", values.toArray());
                List<BrandDomain> brandList = finder.findHQLList();
                for(BrandDomain brand : brandList){
                    for(String value : values){
                        if(value.equals(brand.getName())){
                            result.add(new GroupField(value, UploadUtil.replacePath(brand.getLogo()), 0));
                        }
                    }
                }
            }
        }else{
            for (GroupDocs<String> groupDocs : groupDocsArr) {
                String value = groupDocs.groupValue;
                if(StringUtils.isNotBlank(value)) {
                    result.add(new GroupField(value, value, groupDocs.totalHits));
                }
            }
        }
        groupData.setResult(result);
        return groupData;
    }

    /**
     * 组装内部查询
    */
    public BooleanQuery assembleInnerQuery(String keyword) throws ParseException {
        BooleanQuery innerBooleanQuery = new BooleanQuery();
        /**
        * 1、商品编号查询
         */
        WildcardQuery codeWildcardQuery = new WildcardQuery(new Term("code", keyword + "*"));
        innerBooleanQuery.add(codeWildcardQuery, Occur.SHOULD);

        /**
        * 2、商品名称查询
         */
        QueryParser nameQueryparser = new QueryParser(Version.LUCENE_36, "name", new IKAnalyzer());
        nameQueryparser.setAllowLeadingWildcard(true);
        nameQueryparser.setDefaultOperator(QueryParser.AND_OPERATOR);//存在空格时，空格之间的词是与、或的关系
        Query nameQuery = nameQueryparser.parse(keyword);
        nameQuery.setBoost(5.0f);//提高 默认的相关度排序，
        innerBooleanQuery.add(nameQuery, Occur.SHOULD);

        QueryParser nameQueryparser2 = new QueryParser(Version.LUCENE_36, "name", new IKAnalyzer());
        nameQueryparser2.setAllowLeadingWildcard(true);
        nameQueryparser2.setDefaultOperator(QueryParser.AND_OPERATOR);//存在空格时，空格之间的词是与、或的关系
        Query nameQuery2 = nameQueryparser2.parse(keyword+"*");
        nameQuery2.setBoost(5.0f);//提高 默认的相关度排序，
        innerBooleanQuery.add(nameQuery2, Occur.SHOULD);

        /**
         * 3、商品拼音码查询
         */
        WildcardQuery pyNameWildcardQuery = new WildcardQuery(new Term("pyName", keyword + "*"));
        pyNameWildcardQuery.setBoost(5.0f);
        innerBooleanQuery.add(pyNameWildcardQuery, Occur.SHOULD);
        pyNameWildcardQuery = new WildcardQuery(new Term("pyName", "*" + keyword + "*"));
        pyNameWildcardQuery.setBoost(2.0f);
        innerBooleanQuery.add(pyNameWildcardQuery, Occur.SHOULD);

        /**
        * 4、通用名（通用名的拼音已经包括在pyName里面）
        */
        WildcardQuery byNameWildcardQuery = new WildcardQuery(new Term("byName", "*" + keyword + "*"));
        innerBooleanQuery.add(byNameWildcardQuery, Occur.SHOULD);
        /**
        * 5、生产厂商查询
         */
/*        WildcardQuery manufacturerTermQuery = new WildcardQuery(new Term("manufacturer", "*" + keyword + "*"));
        innerBooleanQuery.add(manufacturerTermQuery, Occur.SHOULD);*/
        /**
        * 6、批准文号查询
         */
        WildcardQuery authorizeNumberWildcardQuery = new WildcardQuery(new Term("authorizeNumber", "*" + keyword + "*"));
        innerBooleanQuery.add(authorizeNumberWildcardQuery, Occur.SHOULD);

        /**
         * 7、商品分类名称
         */
        WildcardQuery cateWildcardQuery = new WildcardQuery(new Term("goodsCategory.name", keyword + "*"));
        innerBooleanQuery.add(cateWildcardQuery, Occur.SHOULD);

        /**
         * 8、商品父分类名称
         */
        WildcardQuery cateParentWildcardQuery = new WildcardQuery(new Term("goodsCategory.parentName", keyword + "*"));
        innerBooleanQuery.add(cateParentWildcardQuery, Occur.SHOULD);

        /**
         * 8、商品顶级父分类名称
         */
        WildcardQuery cateTopParentWildcardQuery = new WildcardQuery(new Term("goodsCategory.topCateName", keyword + "*"));
        innerBooleanQuery.add(cateTopParentWildcardQuery, Occur.SHOULD);

        /**
         * 9、品牌名称
         */
        WildcardQuery brandWildcardQuery = new WildcardQuery(new Term("brand.name", keyword + "*"));
        innerBooleanQuery.add(brandWildcardQuery, Occur.SHOULD);

        /**
         * 10、商品说明书 主治功能
         */
        WildcardQuery functionWildcardQuery = new WildcardQuery(new Term("goodsIntroduction.function", "*" + keyword + "*"));
        innerBooleanQuery.add(functionWildcardQuery, Occur.SHOULD);

        return innerBooleanQuery;
    }
}